---
title: URLs
id: concepts-url
slug: /concepts/url
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

Atlas uses a standard URL format to connect to databases and load schemas and migrations from various sources. The format
below covers the supported parts of a URL, with subsequent sections providing more detailed examples.

```
driver://[username[:password]@]address/[schema|database][?param1=value1&...&paramN=valueN]
```

To inspect a database using a URL, refer to one of the examples below:

<Tabs
defaultValue="mysql"
values={[
{label: 'MySQL', value: 'mysql'},
{label: 'MariaDB', value: 'maria'},
{label: 'PostgreSQL', value: 'postgres'},
{label: 'SQLServer', value: 'sqlserver'},
{label: 'SQLite', value: 'sqlite'},
{label: 'ClickHouse', value: 'clickhouse'},
{label: 'Docker', value: 'docker'},
]}>
<TabItem value="mysql">

Connecting to a local MySQL server (all schemas/databases):
```shell
mysql://localhost:3306/
```

Connecting to a specific MySQL schema (database) with a username and password:
```shell
mysql://user:pass@localhost:3306/schema
```

Connecting using Unix Sockets:
```
mysql+unix:///tmp/mysql.sock

mysql+unix://user:pass@/tmp/mysql.sock

mysql+unix://user@/tmp/mysql.sock?database=dbname
```

</TabItem>
<TabItem value="maria">

Connecting to a local MariaDB server (all schemas/databases):
```shell
maria://localhost:3306/
```

Connecting to a specific MariaDB schema (database) with a username and password:
```shell
maria://user:pass@localhost:3306/schema
```

Connecting using Unix Sockets:
```
maria+unix:///tmp/mysql.sock

maria+unix://user:pass@/tmp/mysql.sock

maria+unix://user@/tmp/mysql.sock?database=dbname
```

</TabItem>
<TabItem value="postgres">

Connecting to a local PostgreSQL database named `database` (all schemas):
```shell
postgres://localhost:5432/database
```

Connecting to a specific PostgreSQL schema named `public`:
```shell
postgres://localhost:5432/database?search_path=public
```

Connecting to a local PostgreSQL with credentials and SSL disabled:
```shell
postgres://postgres:pass@0.0.0.0:5432/database?search_path=public&sslmode=disable
```

</TabItem>
<TabItem value="sqlserver">

Connecting to a default schema of current user:
```shell
sqlserver://sa:P@ssw0rd0995@localhost:1433?database=master&mode=schema
```

Connecting to a local SQLServer database named `master` (all schemas). The user need to have `db_owner` role:
```shell
sqlserver://sa:P@ssw0rd0995@localhost:1433?database=master&mode=database
```

:::note
- The `mode` parameter is Atlas-specific and isn't used for opening the underlying connection.
- The default `mode` is `schema`.
:::
</TabItem>
<TabItem value="sqlite">

Connecting to a local SQLite database (file):
```shell
sqlite://file.db
```

Connecting to an in-memory SQLite database (ephemeral). Useful for `--dev-url`:
```shell
sqlite://file?mode=memory&_fk=1
```

Atlas also supports WebSocket connections to remote `libsql` databases:

```shell
libsql+ws://database-url # For local environments
libsql+wss://database-url
```

</TabItem>
<TabItem value="clickhouse">

Connecting to a local ClickHouse server (all schemas/databases):
```shell
clickhouse://localhost:9000
```

Connecting to a specific ClickHouse schema (database) with a username and password:
```shell
clickhouse://user:pass@localhost:9000/schema
```

</TabItem>
<TabItem value="docker">

Atlas can spin up an ephemeral local docker container for you by specifying a special URL like below. This can be useful
if you need a [dev database](../concepts/dev.mdx) for schema validation or diffing. However, some images like `mysql` /
`mariadb` take quite some time to "boot", before they are ready to be used. For a smoother developing experience
consider spinning up a longer lived container by yourself.

```shell
# PostgreSQL database scope (all schemas).
docker://postgres/15/test

# PostgreSQL specific schema scope.
docker://postgres/15/test?search_path=public

# MySQL server scope (all schemas).
docker://mysql/8

# MySQL specific schema scope.
docker://mysql/8/test

# MySQL server scope (all schemas).
docker://maria/latest

# MySQL specific schema scope.
docker://maria/latest/test
```

</TabItem>
</Tabs>

:::info <a class="sticky-anchor" id={"scope"} href={"#scope"}>Schema vs. Database scope</a>

When the database URL is set to a specific schema (e.g., `mysql://:3306/dev`), the scope of the work done by Atlas
(inspection, diffing, planning, applying, etc.) is limited to one schema. As a result, DDL statements printed during
diffing or planning will be formatted without schema qualifiers and can be executed on any schema. e.g., `table` instead
of `schema.table`

However, if the database URL does not specify a schema (e.g., `mysql://:3306/`), Atlas operates on the selected schemas
(defaulting to all), and the generated DDL statements include schema qualifiers. e.g., `schema.table` instead of `table`.
:::

## Supported Schemes

Besides the standard database URLs mentioned above, Atlas supports various schemes for loading schemas and migration states:

#### `file`

The `file://` scheme is used to load schema state from a local file or a directory. The supported extensions
are `.sql` and `.hcl`. For example:

```shell
file://path/to/schema.hcl
file://path/to/schema.sql
file://path/to/schemadir

file://path/to/migrations
file://path/to/migrations?version=20231201182011
```

#### `atlas`

The `atlas://` scheme is used to load the state of a remote schema or a migrations directory from the Atlas Cloud, the
schema registry, and migrations artifactory of Atlas. For example:

```shell
atlas://dir-slug
atlas://dir-slug?version=20231201182011
```

#### `env`

The `env://` scheme is useful for referencing the state of a schema after it has been loaded by a data source. For example:

```hcl title="atlas.hcl"
data "external_schema" "orm" {
  program = [
    ...
  ]
}

env "dev" {
  orm = data.external_schema.orm
}
```
```shell
atlas schema inspect --env dev -u env://orm
```

#### `ent`

The `ent://` scheme is used to load the state an [ent](https://entgo.io) schema. For example:

```shell
ent://path/to/ent/schema
```

## SSL/TLS Mode

The default SSL mode for Postgres is `required`. Please follow the
[Postgres documentation](https://www.postgresql.org/docs/current/libpq-ssl.html)
for configuring your SSL connection for your database, or set SSL mode to `disable`
with the search parameter `?sslmode=disable`. For local databases,
disabling SSL is appropriate when inspecting and applying schema changes.

MySQL does not require TLS by default. However, you can require TLS
with the `?tls=true` search parameter.

## Non-alphanumeric characters

Database URLs often contain passwords and other information which may contain non-alphanumeric characters.
These characters must be escaped using standard URL encoding, in order to be parsed correctly.
As a convenience, users may use the `urlescape` function in an `atlas.hcl` [project file](/concepts/url) to escape
these characters automatically.

Suppose your password is `h:e!:l:l:o` and it is stored as an environment variable named `DB_PASSWORD`, you
can read this value and escape it using the `urlescape` function:

```hcl title="atlas.hcl"
locals {
  db_pass = urlescape(env("DB_PASSWORD"))
}

env "local" {
    url = "postgres://user:${local.db_pass}@localhost:5432/database"
}
```

The `urlescape` function return the escaped value: `h%3Ae%21%3Al%3Al%3Ao`.